home *** CD-ROM | disk | FTP | other *** search
- /* example of file access with RDCF 2.0 and CACHE 1.1 */
- /* public domain - no restrictions on use */
- /* Plain Vanilla Corporation - January 15, 1993 */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <string.h>
- #include <process.h>
- #include <dos.h>
- #include <io.h>
- #include <alloc.h>
- #include "rdcf2.h"
- #include "cache.h"
-
- static unsigned drive_access(int write, unsigned drive, unsigned LSN,
- void *buffer)
- {
- _SI; _DI;
- return write ? abswrite(drive, 1, LSN, buffer) :
- absread(drive, 1, LSN, buffer);
- }
-
- struct cache *cache;
-
- static unsigned cached_drive_access(int write, unsigned drive,
- unsigned sector, void *buffer)
- {
- return write && drive > 1 ? 1 :
- cache_access(cache, write, drive, sector, buffer);
- }
-
- static char *ERROR_MESSAGE[] =
- {
- "NO ERROR ",
- "ACCESS DENIED ",
- "DIRECTORY CONFLICT ",
- "DIRECTORY FULL ",
- "DISK FORMAT ERROR ",
- "DRIVE ERROR ",
- "FILE FORMAT ERROR ",
- "INVALID DIRECTORY ",
- "INVALID SPEC ",
- "MODE ERROR ",
- "FILE NOT FOUND ",
- "RENAMING ERROR ",
- "SEEK OUT OF RANGE ",
- "UNRECOVERABLE FILE "
- };
-
- static char HELP[] =
- " COPY source destination\n"
- " DATE file month-day-year hour:min:sec\n"
- " DEL file\n"
- " DIR directory\n"
- " DIRSORT directory\n"
- " EXIT\n"
- " HELP\n"
- " MD directory\n"
- " MCOPY files directory\n"
- " MOVE source destination\n"
- " RECOVER file\n"
- " REN old new\n"
- " TYPE file\n"
- " UNDEL file\n"
- " VOLUME name\n"
- " WIPE drive\n";
-
- static void rdcf_error_message(int n)
- {
- if (n == RDCF_DRIVE_ERROR)
- printf("DRIVE ERROR ON DRIVE %c:\n", cache->error_drive + 'A');
- else
- puts(ERROR_MESSAGE[-n]);
- }
-
- static void disk_write_error(void)
- {
- printf("Disk write error on drive %c:\n", cache->error_drive + 'A');
- }
-
- void rdcf_get_date_and_time(struct rdcf_date_and_time *p)
- {
- struct date d;
- struct time t;
- int day;
- getdate(&d);
- day = d.da_day;
- gettime(&t);
- getdate(&d);
- if (day != d.da_day) gettime(&t);
- p->month = d.da_mon;
- p->day = d.da_day;
- p->year = d.da_year;
- p->hour = t.ti_hour;
- p->minute = t.ti_min;
- p->second = t.ti_sec;
- }
-
- static unsigned char scratch_buffer[RDCF_SECTOR_SIZE];
- struct rdcf f = {scratch_buffer, cached_drive_access};
- struct rdcf g = {scratch_buffer, cached_drive_access};
- static char buffer[1024];
-
- static void three_numbers(char *s, unsigned *n1, unsigned *n2, unsigned *n3)
- {
- if (isdigit(*s))
- {
- *n1 = 0;
- do *n1 = 10 * (*n1) + *s++ - '0'; while (isdigit(*s));
- }
- if (*s != 0) s++;
- if (isdigit(*s))
- {
- *n2 = 0;
- do *n2 = 10 * (*n2) + *s++ - '0'; while (isdigit(*s));
- }
- if (*s != 0) s++;
- if (isdigit(*s))
- {
- *n3 = 0;
- do *n3 = 10 * (*n3) + *s++ - '0'; while (isdigit(*s));
- }
- }
-
-
- static int break_flag;
-
- static void interrupt Ctrl_C_handler() {break_flag = 1;}
-
- static int copy(char *source, char *destination)
- {
- if (rdcf_open(&f, source, RDCF_READ))
- {
- rdcf_error_message(f.result);
- return 0;
- }
- if (rdcf_open(&g, destination, RDCF_CREATE))
- {
- rdcf_error_message(g.result);
- return 0;
- }
- while (!break_flag)
- {
- int n = rdcf_read(&f, buffer, sizeof(buffer));
- if (n<0)
- {
- rdcf_error_message(n);
- return 0;
- }
- if (n==0) break;
- n = rdcf_write(&g, buffer, n);
- if (n<0)
- {
- rdcf_error_message(n);
- return 0;
- }
- if (n==0) break;
- }
- rdcf_close(&f);
- rdcf_close(&g);
- rdcf_date_and_time(&g, destination, &f.file.date_and_time);
- return 1;
- }
-
- static char *directory_and_specs(char *directory, char *specs)
- {
- static char s[82];
- char *p = s;
- int c;
- while (*directory != 0) c = *p++ = *directory++;
- if (c != ':') *p++ = '\\';
- strcpy(p, specs);
- return s;
- }
-
- static void command(void)
- {
- char *arg[4];
- {
- static struct
- {
- unsigned char capacity;
- unsigned char count;
- char text[70];
- } buffer = {sizeof(buffer.text), 0, '\r'};
- static char buffer2[sizeof(buffer.text)];
- unsigned i;
- register char *p;
- fputs("FILES>", stdout);
- bdos(10, (unsigned)(&buffer), 0);
- bdos(2, '\n', 0);
- for (i=0, p=buffer2; i<buffer.count; i++)
- *p++ = toupper(buffer.text[i]);
- *p = 0;
- p = buffer2;
- for (i=0; i<4; i++)
- {
- while (*p==' ' || *p=='\t') p++;
- arg[i] = p;
- while (*p!=' ' && *p!='\t' && *p!=0) p++;
- if (*p!=0) *p++ = 0;
- }
- }
- if (strcmp(arg[0],"COPY")==0)
- {
- break_flag = 0;
- copy (arg[1], arg[2]);
- }
- else if (strcmp(arg[0],"DATE")==0)
- {
- unsigned month = 1;
- unsigned day = 1;
- unsigned year = 1980;
- unsigned hour = 0;
- unsigned minute = 0;
- unsigned second = 0;
- struct rdcf_date_and_time d;
- three_numbers(arg[2], &month, &day, &year);
- d.month = month;
- d.day = day;
- if (80 <= year && year <= 99) year += 1900;
- else if (year < 70) year += 2000;
- d.year = year;
- three_numbers(arg[3], &hour, &minute, &second);
- d.hour = hour;
- d.minute = minute;
- d.second = second;
- if (rdcf_date_and_time(&f, arg[1], &d) != 0)
- {
- rdcf_error_message(f.result);
- return;
- }
- }
- else if (strcmp(arg[0],"DEL")==0)
- {
- if (rdcf_delete(&f, arg[1]) != 0)
- {
- rdcf_error_message(f.result);
- return;
- }
- }
- else if (strcmp(arg[0],"DIR")==0)
- {
- static char drive[] = "X:";
- struct
- {
- struct
- {
- unsigned current;
- unsigned deleted;
- } file, directory, volume;
- } count;
- memset(&count, 0, sizeof(count));
- break_flag = 0;
- if (rdcf_get_file_information(&f, arg[1], 0) != RDCF_DIRECTORY_FULL) do
- {
- if (f.result == RDCF_FILE_NOT_FOUND || f.result == 0)
- {
- if (f.result == RDCF_FILE_NOT_FOUND) f.file.spec[0] = '?';
- printf("%-12s ", f.file.spec);
- if (f.file.attribute & RDCF_DIRECTORY)
- {
- if (f.result == 0) count.directory.current++;
- else count.directory.deleted++;
- printf(" <DIR> ");
- }
- else if (f.file.attribute & RDCF_VOLUME)
- {
- if (f.result == 0) count.volume.current++;
- else count.volume.deleted++;
- printf(" <VOL> ");
- }
- else
- {
- if (f.result == 0) count.file.current++;
- else count.file.deleted++;
- printf("%8ld ", f.file.size);
- }
- printf("%c%c%c%c%c%c ",
- f.file.attribute&RDCF_ARCHIVE ? 'A' : ' ',
- f.file.attribute&RDCF_DIRECTORY ? 'D' : ' ',
- f.file.attribute&RDCF_HIDDEN ? 'H' : ' ',
- f.file.attribute&RDCF_READ_ONLY ? 'R' : ' ',
- f.file.attribute&RDCF_SYSTEM ? 'S' : ' ',
- f.file.attribute&RDCF_VOLUME ? 'V' : ' ');
- printf("%02d-%02d-%04d %02d:%02d:%02d%s\n",
- f.file.date_and_time.month, f.file.date_and_time.day,
- f.file.date_and_time.year, f.file.date_and_time.hour,
- f.file.date_and_time.minute, f.file.date_and_time.second,
- f.result == RDCF_FILE_NOT_FOUND ? " DELETED" : "");
- }
- else
- {
- rdcf_error_message(f.result);
- return;
- }
- } while (rdcf_next_file_information(&f) != RDCF_DIRECTORY_FULL &&
- !break_flag);
- printf("\n current deleted total\n");
- printf(" ------- ------- -------\n");
- printf(" files %7d %7d %7d\n", count.file.current,
- count.file.deleted, count.file.current+count.file.deleted);
- printf(" directories %7d %7d %7d\n", count.directory.current,
- count.directory.deleted, count.directory.current+count.directory.deleted);
- printf(" volume labels %7d %7d %7d\n", count.volume.current,
- count.volume.deleted, count.volume.current+count.volume.deleted);
- printf(" ------- ------- -------\n");
- printf(" total %7d %7d %7d\n",
- count.file.current+count.directory.current+count.volume.current,
- count.file.deleted+count.directory.deleted+count.volume.deleted,
- count.file.current+count.directory.current+count.volume.current+
- count.file.deleted+count.directory.deleted+count.volume.deleted);
- printf(" ======= ======= =======\n");
- drive[0] = arg[1][0];
- printf("\n %ld bytes free\n", rdcf_free_space(&f, drive));
- }
- else if (strcmp(arg[0],"DIRSORT")==0)
- {
- int mode = RDCF_NAME_EXTENSION;
- char *p = arg[2];
- if (*p == 'E') mode = RDCF_EXTENSION_NAME;
- else if (*p == 'D') mode = RDCF_DATE_TIME;
- else if (*p == 'S') mode = RDCF_SIZE;
- if (*p != 0 && *++p == 'R') mode += RDCF_REVERSE;
- if (rdcf_sort_directory(&f, arg[1], mode))
- {
- rdcf_error_message(f.result);
- return;
- }
- }
- else if (strcmp(arg[0],"EXIT")==0)
- {
- if (cache_flush_and_clear(cache, -1)) disk_write_error();
- bdos(13,0,0);
- exit(0);
- }
- else if (strcmp(arg[0],"HELP")==0)
- puts(HELP);
- else if (strcmp(arg[0],"MD")==0)
- {
- if (rdcf_directory(&f, arg[1]) != 0)
- rdcf_error_message(f.result);
- }
- else if (strcmp(arg[0],"MOVE")==0)
- {
- if (rdcf_move(&f, arg[1], arg[2]) != 0)
- rdcf_error_message(f.result);
- }
- else if (strcmp(arg[0],"MCOPY")==0)
- {
- unsigned k = 0;
- unsigned number_of_files = 0;
- char *old_directory = arg[1];
- char *pattern = NULL;
- /* find end of directory path */
- {
- char *p;
- for (p = arg[1]; *p != 0; p++)
- if (*p == ':' || *p == '\\') pattern = p;
- }
- old_directory = arg[1];
- if (pattern == NULL)
- {
- puts("Invalid specifications or missing pattern");
- return;
- }
- if (*pattern == ':')
- {
- old_directory--;
- old_directory[0] = old_directory[1];
- old_directory[1] = ':';
- }
- *pattern++ = 0;
- if (*pattern == 0)
- {
- puts("Missing pattern\n");
- return;
- }
- break_flag = 0;
- while (rdcf_get_file_information(&f, old_directory, k++) !=
- RDCF_DIRECTORY_FULL && !break_flag)
- {
- if (f.result != RDCF_FILE_NOT_FOUND &&
- (f.file.attribute & RDCF_DIRECTORY+RDCF_VOLUME) == 0 &&
- rdcf_match(f.file.spec, pattern))
- {
- static char old_specs[82];
- strcpy(old_specs, directory_and_specs(old_directory, f.file.spec));
- printf("%s --> %s\n", old_specs,
- directory_and_specs(arg[2], f.file.spec));
- if (!copy(old_specs, directory_and_specs(arg[2], f.file.spec))) return;
- number_of_files++;
- if (cache->dirty >= cache->empty+cache->clean && cache_flush(cache, -1))
- {
- disk_write_error();
- return;
- }
- }
- }
- printf("%d file(s) copied\n", number_of_files);
- }
- else if (strcmp(arg[0],"RECOVER")==0)
- {
- if (rdcf_recover(&f, arg[1]) != 0)
- rdcf_error_message(f.result);
- }
- else if (strcmp(arg[0],"REN")==0)
- {
- if (rdcf_rename(&f, arg[1], arg[2]) != 0)
- rdcf_error_message(f.result);
- }
- else if (strcmp(arg[0],"TYPE")==0)
- {
- if (rdcf_open(&f, arg[1], RDCF_READ))
- {
- rdcf_error_message(f.result);
- return;
- }
- break_flag = 0;
- while (!break_flag)
- {
- int n = rdcf_read(&f, buffer, sizeof(buffer));
- if (n<0)
- {
- rdcf_error_message(n);
- return;
- }
- if (n==0) break;
- _write(1, buffer, n);
- }
- fputs("\n", stdout);
- rdcf_close(&f);
- }
- else if (strcmp(arg[0],"UNDEL")==0)
- {
- if (rdcf_open(&f, arg[1], RDCF_READ) == 0)
- {
- printf("File exists and is not deleted\n");
- return;
- }
- if (f.result != RDCF_FILE_NOT_FOUND)
- {
- rdcf_error_message(f.result);
- return;
- }
- if (rdcf_undelete(&f, arg[1]))
- {
- rdcf_error_message(f.result);
- return;
- }
- printf("File was %s recovered\n", f.position == 0 ? "fully" : "partly");
- }
- else if (strcmp(arg[0],"VOLUME")==0)
- {
- if (*arg[2] == 0)
- {
- if (rdcf_get_volume(&f, arg[1]) ==
- RDCF_FILE_NOT_FOUND)
- {
- printf("No volume label\n");
- }
- else if (f.result != 0)
- {
- rdcf_error_message(f.result);
- return;
- }
- else
- printf("Volume label is %s\n", f.file.spec);
- }
- else
- {
- char s[132];
- strcpy(s, arg[1]);
- strcpy(s+2, arg[2]);
- if (rdcf_set_volume(&f, s) != 0)
- {
- rdcf_error_message(f.result);
- return;
- }
- }
- }
- else if (strcmp(arg[0],"WIPE")==0)
- {
- if (rdcf_wipe_drive(&f, arg[1]))
- rdcf_error_message(f.result);
- }
- else if (*arg[0] != 0)
- puts("?????");
- }
-
- void main()
- {
- unsigned n;
- for (n = 80; n > 0 ; n -= 10)
- {
- cache = cache_initialize(drive_access, n, RDCF_SECTOR_SIZE);
- if (cache != NULL)
- {
- int input_from_device = ioctl(0, 0) & 0x80;
- setvect(0x23, Ctrl_C_handler);
- printf("Using %d cache buffers\n", n);
- while (1)
- {
- command();
- if (input_from_device)
- {
- if (cache_flush_and_clear(cache, -1))
- disk_write_error();
- }
- else
- {
- if (cache->dirty >= cache->empty+cache->clean &&
- cache_flush(cache, -1))
- {
- disk_write_error();
- return;
- }
- }
- }
- }
- }
- puts("Insufficient memory");
- }
-
-